package com.ideal.manage.esms.service.diagnostic;

import com.alibaba.fastjson.JSONObject;
import com.ideal.manage.esms.bean.DTO.PageDto;
import com.ideal.manage.esms.bean.diagnostic.DiagnoseResultInfo;
import com.ideal.manage.esms.bean.project.EquipmentManage;
import com.ideal.manage.esms.repository.diagnostic.DiagnoseResultInfoRepository;
import com.ideal.manage.esms.repository.framework.SpecificationOperator;
import com.ideal.manage.esms.service.project.EquipmentManageService;
import com.ideal.manage.esms.util.HttpRequests;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created By Dai On 2018/5/29
 * Remark: 诊断分析数据结果表 Service
 */
@Service
public class DiagnoseResultInfoService {

    @Autowired
    private DiagnoseResultInfoRepository diagnoseResultInfoRepository;
    @Autowired
    private EquipmentManageService equipmentManageService;

    private static final Logger logger = LoggerFactory.getLogger(DiagnoseResultInfoService.class);

    /**
     * 根据名称获取最近的一次数据
     *
     * @param id
     * @param name
     * @return
     */
    public JSONObject refreshThisValue(String id, String name) {
        // 1. 要返回的数据
        JSONObject jsonObject = new JSONObject();
        // 2. 获取最大的时间
        jsonObject = getValue(id, name, jsonObject);
        // 4. 获取变化值的时间
        Date date = jsonObject.getDate("date");
        if ("xhcs".equals(name)) {  // 如果是循环次数的话 要重新获取第二大的时间和对应的值
            date = diagnoseResultInfoRepository.findNextTimeByIdAndName(id, name, date);
        } else {    // 如果是其他的话，就要获取变化量最大的时间和对应的值了
            date = diagnoseResultInfoRepository.findMaxTimeByIdAndName(id, name + "bhl");   //变化量
        }
        // 5. 如果时间为空就是变化量不知道
        if (date == null) {
            jsonObject.put("change_value", "暂无数据");
            return jsonObject;
        }
        // 6. 获取变化量
        String change_value;
        change_value = diagnoseResultInfoRepository.findNowValueByIdAndNameAndTime(id, name, date);
        if ("xhcs".equals(name)) {  //循环次数
            change_value = (Integer.parseInt(change_value) - Integer.parseInt(jsonObject.getString("value"))) + "";
        }
        jsonObject.put("change_value", change_value);
        return jsonObject;
    }

    /**
     * 获取总容量下面的各个信息
     *
     * @return
     */
    public JSONObject getZDLInfo(String id) {
        JSONObject jsonObject = new JSONObject();
        jsonObject = getValue(id, "dtrlbhl", jsonObject, "dtrlbhl");    //单体容量变化量
        jsonObject = getValue(id, "zdyxcddl", jsonObject, "zdyxcddl");  //最大允许充电电流
        jsonObject = getValue(id, "cddlqqz", jsonObject, "cddlqqz");    //充电电流请求值
        jsonObject = getValue(id, "stfddl", jsonObject, "stfddl");      //瞬态放电电流
        jsonObject = getValue(id, "stcddl", jsonObject, "stcddl");      //瞬态充电电流
        jsonObject = getValue(id, "wtfddl", jsonObject, "wtfddl");      //稳态放电电流
        jsonObject = getValue(id, "wtcddl", jsonObject, "wtcddl");      //稳态充电电流
        return jsonObject;
    }

    /**
     * 获取值
     *
     * @param id
     * @param name
     * @param jsonObject
     * @return
     */
    public JSONObject getValue(String id, String name, JSONObject jsonObject) {
        // 2. 获取最大的时间
        Date date = diagnoseResultInfoRepository.findMaxTimeByIdAndName(id, name);
        if (date == null) { // 如果最大时间都不存在的话 那就是没有数据
            jsonObject.put("value", "暂无数据");
            jsonObject.put("change_value", "暂无数据");
            jsonObject.put("date", new Date());
            return jsonObject;
        }
        jsonObject.put("date", date);
        // 3. 获取对应时间的值
        String value = diagnoseResultInfoRepository.findNowValueByIdAndNameAndTime(id, name, date);
        jsonObject.put("value", value);
        return jsonObject;
    }

    /**
     * 获取的值放一个jsonObject时使用
     *
     * @param id
     * @param name
     * @param jsonObject
     * @param value_name
     * @return
     */
    public JSONObject getValue(String id, String name, JSONObject jsonObject, String value_name) {
        // 2. 获取最大的时间
        Date date = diagnoseResultInfoRepository.findMaxTimeByIdAndName(id, name);
        if (date == null) { // 如果最大时间都不存在的话 那就是没有数据
            jsonObject.put(value_name, "暂无数据");
            return jsonObject;
        }
        // 3. 获取对应时间的值
        String value = diagnoseResultInfoRepository.findNowValueByIdAndNameAndTime(id, name, date);
        jsonObject.put(value_name, value);
        return jsonObject;
    }

    /**
     * 直接获取指定名字的值
     *
     * @param id
     * @param name
     * @return
     */
    public Double getValue(String id, String name) {
        // 2. 获取最大的时间
        Date date = diagnoseResultInfoRepository.findMaxTimeByIdAndName(id, name);
        if (date == null) { // 如果最大时间都不存在的话 那就是没有数据
            return 0.0;
        }
        // 3. 获取对应时间的值
        String valueStr = diagnoseResultInfoRepository.findNowValueByIdAndNameAndTime(id, name, date);
        if (StringUtils.isBlank(valueStr)) {
            valueStr = "0.0";
        }
        Double value = Double.parseDouble(valueStr);
        return value;
    }

    /**
     * 获取上一个值
     *
     * @param id
     * @param name
     * @return
     */
    public Double getLastValue(String id, String name) {
        // 1. 获取最大的时间
        Date date = diagnoseResultInfoRepository.findMaxTimeByIdAndName(id, name);
        if (date == null) {
            return 0.0;
        }
        // 2. 获取第二大时间
        date = diagnoseResultInfoRepository.findNextTimeByIdAndName(id, name, date);
        // 3. 获取对应的值
        String next_value_str = diagnoseResultInfoRepository.findNowValueByIdAndNameAndTime(id, name, date);
        if (StringUtils.isBlank(next_value_str)) {
            next_value_str = "0.0";
        }
        Double next_value = Double.parseDouble(next_value_str);
        return next_value;
    }

    /**
     * 获取电池包一致性
     *
     * @param id
     * @return
     */
    public JSONObject getBatteryInfo(String id) {
        JSONObject jsonObject = new JSONObject();
        // 1. 容量
        jsonObject = getValue(id, "dtrlbzc", jsonObject, "rl_bzc");
        jsonObject = getValue(id, "dtrlfc", jsonObject, "rl_fc");
        jsonObject = getValue(id, "dtrlqwz", jsonObject, "rl_qwz");
        jsonObject = getValue(id, "dtrlbyxs", jsonObject, "rl_byxs");
        jsonObject = getValue(id, "dtrlsfwsql", jsonObject, "rl_sfwsq1");
        jsonObject = getValue(id, "dtrlsfwsqm", jsonObject, "rl_sfwsqm");
        jsonObject = getValue(id, "dtrlsfwsqu", jsonObject, "rl_sfwsqu");
        jsonObject = getValue(id, "dtrlsfwsc", jsonObject, "rl_sfwsc");
        jsonObject = getValue(id, "dtrlyzx", jsonObject, "rl_yzx");
        // 2. SOC
        jsonObject = getValue(id, "SOC_bzc", jsonObject, "SOC_bzc");
        jsonObject = getValue(id, "SOC_fc", jsonObject, "SOC_fc");
        jsonObject = getValue(id, "SOC_qwz", jsonObject, "SOC_qwz");
        jsonObject = getValue(id, "SOC_byxs", jsonObject, "SOC_byxs");
        jsonObject = getValue(id, "SOC_sfwsq1", jsonObject, "SOC_sfwsq1");
        jsonObject = getValue(id, "SOC_sfwsqm", jsonObject, "SOC_sfwsqm");
        jsonObject = getValue(id, "SOC_sfwsqu", jsonObject, "SOC_sfwsqu");
        jsonObject = getValue(id, "SOC_sfwsc", jsonObject, "SOC_sfwsc");
        jsonObject = getValue(id, "SOC_yzx", jsonObject, "SOC_yzx");
        // 3. DCIR
        jsonObject = getValue(id, "DCIR_bzc", jsonObject, "DCIR_bzc");
        jsonObject = getValue(id, "DCIR_fc", jsonObject, "DCIR_fc");
        jsonObject = getValue(id, "DCIR_qwz", jsonObject, "DCIR_qwz");
        jsonObject = getValue(id, "DCIR_byxs", jsonObject, "DCIR_byxs");
        jsonObject = getValue(id, "DCIR_sfwsq1", jsonObject, "DCIR_sfwsq1");
        jsonObject = getValue(id, "DCIR_sfwsqm", jsonObject, "DCIR_sfwsqm");
        jsonObject = getValue(id, "DCIR_sfwsqu", jsonObject, "DCIR_sfwsqu");
        jsonObject = getValue(id, "DCIR_sfwsc", jsonObject, "DCIR_sfwsc");
        jsonObject = getValue(id, "DCIR_yzx", jsonObject, "DCIR_yzx");
        // 4. 电压
        jsonObject = getValue(id, "dy_bzc", jsonObject, "dy_bzc");
        jsonObject = getValue(id, "dy_fc", jsonObject, "dy_fc");
        jsonObject = getValue(id, "dy_qwz", jsonObject, "dy_qwz");
        jsonObject = getValue(id, "dy_byxs", jsonObject, "dy_byxs");
        jsonObject = getValue(id, "dy_sfwsq1", jsonObject, "dy_sfwsq1");
        jsonObject = getValue(id, "dy_sfwsqm", jsonObject, "dy_sfwsqm");
        jsonObject = getValue(id, "dy_sfwsqu", jsonObject, "dy_sfwsqu");
        jsonObject = getValue(id, "dy_sfwsc", jsonObject, "dy_sfwsc");
        jsonObject = getValue(id, "dy_yzx", jsonObject, "dy_yzx");
        // 5. 温度
        jsonObject = getValue(id, "wd_bzc", jsonObject, "wd_bzc");
        jsonObject = getValue(id, "wd_fc", jsonObject, "wd_fc");
        jsonObject = getValue(id, "wd_qwz", jsonObject, "wd_qwz");
        jsonObject = getValue(id, "wd_byxs", jsonObject, "wd_byxs");
        jsonObject = getValue(id, "wd_sfwsq1", jsonObject, "wd_sfwsq1");
        jsonObject = getValue(id, "wd_sfwsqm", jsonObject, "wd_sfwsqm");
        jsonObject = getValue(id, "wd_sfwsqu", jsonObject, "wd_sfwsqu");
        jsonObject = getValue(id, "wd_sfwsc", jsonObject, "wd_sfwsc");
        jsonObject = getValue(id, "wd_yzx", jsonObject, "wd_yzx");
        return jsonObject;
    }

    /**
     * 保存诊断结果
     *
     * @param diagnoseResultInfo
     */
    public void saveDiagnoseResultInfo(DiagnoseResultInfo diagnoseResultInfo) {
        diagnoseResultInfoRepository.save(diagnoseResultInfo);
    }

//    /**
//     * 查询一个月内的数据
//     * @param startDate
//     * @return
//     */
//    public List<DiagnoseResultInfo> findDataByTime(String name,Date startDate){
//        return diagnoseResultInfoRepository.findDataByTime(name,startDate);
//    }

    /**
     * 查询最新的一次数据
     */
    public List<DiagnoseResultInfo> findLastedData(String id, Date startDate) {
        return diagnoseResultInfoRepository.findLastedData(id, startDate);
    }

    public Date findLastedDate(String id) {
        return diagnoseResultInfoRepository.findLastedDate(id);
    }

    /**
     * 获取电池单体诊断结果值
     *
     * @param id
     */
    public Map<String, String> getDtData(String id) {
        // 创建一个集合存放数据
        Map<String, String> newDataDC = new HashMap<String, String>();
        //数据过滤
        String dtsoc = "dtsoc_";
        String dtzz = "dtzz_";
        String dtrl = "dtrl_";
        List<String> falg = falg(id, dtsoc, dtzz, dtrl);
        getDtsocData(id, newDataDC, falg.get(0));
        getDtzzData(id, newDataDC, falg.get(1));
        getDtrlData(id, newDataDC, falg.get(2));

        return newDataDC;

    }

    /**
     * 获取单体SOC
     *
     * @param id
     * @param newDataDC
     * @param dtSoc
     * @return
     */
    public Map<String, String> getDtsocData(String id, Map<String, String> newDataDC, String dtSoc) {
        if (dtSoc == null) {
            String dtsoc = "dtsoc_";
            String dtzz = "dtzz_";
            String dtrl = "dtrl_";
            List<String> falg = falg(id, dtsoc, dtzz, dtrl);
            dtSoc = falg.get(0);
        }

        //查询数据库获取值(这里是单体SOC)
        List<DiagnoseResultInfo> newData = diagnoseResultInfoRepository.findNewData(dtSoc);

        // 定义存放
        String valueSoc = null;
        String resultValSoc = null;
        if (newData.size() > 0) {
            DiagnoseResultInfo maxData = newData.get(0);
            DecimalFormat df = new DecimalFormat("0.00");
            resultValSoc = df.format(Double.valueOf(maxData.getResultVal()));

            //获取时间最近的一条数据
            if (newData.size() == 1) {
                valueSoc = "0.0";
            }else {
                DiagnoseResultInfo minData = newData.get(1);
                String resultValM = minData.getResultVal();

                valueSoc = String.valueOf(df.format(Double.valueOf(resultValSoc) - Double.valueOf(resultValM)));
            }
        } else {
            resultValSoc = "0.0";
            valueSoc = "0.0";
        }
        if (valueSoc == null) {
            valueSoc = "0.0";
        }
        newDataDC.put("dtsoc", resultValSoc);
        newDataDC.put("valueSoc", valueSoc);
        return newDataDC;

    }

    /**
     * 获取单体阻值
     *
     * @param id
     * @param newDataDC
     * @param dtZz
     * @return
     */
    public Map<String, String> getDtzzData(String id, Map<String, String> newDataDC, String dtZz) {
        if (dtZz == null) {
            String dtsoc = "dtsoc_";
            String dtzz = "dtzz_";
            String dtrl = "dtrl_";
            List<String> falg = falg(id, dtsoc, dtzz, dtrl);
            dtZz = falg.get(1);
        }

        //查询数据库获取值(这里是单体阻值)
        List<DiagnoseResultInfo> newData1 = diagnoseResultInfoRepository.findNewData(dtZz);
        // 定义存放
        String valueZZ = null;
        String resultValZZ = null;

        if (newData1.size() > 0) {
            DecimalFormat df = new DecimalFormat("0.00");
            DiagnoseResultInfo maxDataZZ = newData1.get(0);
            resultValZZ = df.format(Double.valueOf(maxDataZZ.getResultVal()));
            if (newData1.size() == 1) {
                valueZZ = "0.0";
            } else {
                DiagnoseResultInfo minData = newData1.get(1);
                String resultValM = minData.getResultVal();
                valueZZ = String.valueOf(df.format(Double.valueOf(resultValZZ) - Double.valueOf(resultValM)));
            }
        } else {
            resultValZZ = "0.0";
            valueZZ = "0.0";
        }

        if (valueZZ == null) {
            valueZZ = "0.0";
        }
        newDataDC.put("dtzz", resultValZZ);
        newDataDC.put("valueZz", valueZZ);
        return newDataDC;

    }

    /**
     * 过滤唯一标识
     *
     * @param id
     * @param newDataDC
     * @param dtRl
     * @return
     */
    public Map<String, String> getDtrlData(String id, Map<String, String> newDataDC, String dtRl) {

        if (dtRl == null) {
            String dtsoc = "dtsoc_";
            String dtzz = "dtzz_";
            String dtrl = "dtrl_";
            List<String> falg = falg(id, dtsoc, dtzz, dtrl);
            dtRl = falg.get(2);
        }

        //查询数据库获取值(这里是单体容量)
        List<DiagnoseResultInfo> newData2 = diagnoseResultInfoRepository.findNewData(dtRl);

        // 定义存放
        String valueRL = null;
        String resultValRL = null;
        if (newData2.size() > 0) {
            DecimalFormat df = new DecimalFormat("0.00");
            DiagnoseResultInfo maxDataRL = newData2.get(0);
            resultValRL = df.format(Double.valueOf(maxDataRL.getResultVal()));
            if (newData2.size() == 1) {
                valueRL = "0.0";
            } else {
                DiagnoseResultInfo minData = newData2.get(1);
                String resultValM = minData.getResultVal();
                valueRL = String.valueOf(df.format(Double.valueOf(resultValRL) - Double.valueOf(resultValM)));
            }

        } else {
            resultValRL = "0.0";
            valueRL = "0.0";
        }
        if (valueRL == null) {
            valueRL = "0.0";
        }
        newDataDC.put("dtrl", resultValRL);
        newDataDC.put("valueRl", valueRL);
        return newDataDC;
    }

    /**
     * 获取相应的标识
     *
     * @param id
     * @param dtsoc
     * @param dtzz
     * @param dtrl
     * @return
     */
    public List<String> falg(String id, String dtsoc, String dtzz, String dtrl) {
        // 获取唯一标识
        EquipmentManage data = equipmentManageService.findOne(id);
        String code = data.getCode().replaceAll("_", "");
        String falg = code.substring(code.indexOf("0"));
        // 创建查询标识
        String dtsocInfo = dtsoc + falg;
        String dtzzInfo = dtzz + falg;
        String dtrlInfo = dtrl + falg;
        List<String> strings = new ArrayList<>();
        strings.add(dtsocInfo);
        strings.add(dtzzInfo);
        strings.add(dtrlInfo);
        return strings;
    }

    /**
     * 诊断分析- 诊断结果-分页查询
     *
     * @param pageNum
     * @param request
     * @param startDate 默认空为今天
     * @param endDate   默认空为今天
     * @return
     * @equipmentName 设备名称
     */
    public PageDto findDiagnoseResultInfoOnPage(int pageNum, HttpServletRequest request, String equipmentName, String startDate, String endDate) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        if (startDate == null || "".equals(startDate)) {
            startDate = simpleDateFormat.format(new Date());
        }
        if (endDate == null || "".equals(endDate)) {
            endDate = simpleDateFormat.format(new Date());
        }

        String sql = "SELECT a.*, d.name FROM esms_diagnose_result_info a, (SELECT max(info.create_time) last_time, info.set_val FROM esms_diagnose_result_info info " +
                " where date_format(info.create_time, '%Y-%m-%d') >= '" + startDate + "'" +
                " and date_format(info.create_time, '%Y-%m-%d') <= '" + endDate + "'" +
                " GROUP BY set_val ) b, sys_equipment_manage d WHERE a.set_val = b.set_val AND a.create_time = b.last_time AND a.equipment_id = d.id AND d.is_valid = 1 ";

        if (equipmentName != null || !"".equals(equipmentName)) {
            sql += " AND d.name LIKE '%" + equipmentName + "%' ";
        }
        Sort sort = new Sort(Sort.Direction.DESC, "create_time");
        List<SpecificationOperator> operators = HttpRequests.getParametersStartingWith(request, "Q_");
        //增加删除标识的过滤
        SpecificationOperator isValid = new SpecificationOperator("is_valid", "1", "EQ");
        operators.add(isValid);
        Pageable pageable = new PageRequest(pageNum, 10, sort);
        Page<DiagnoseResultInfo> page = diagnoseResultInfoRepository.findAllBySql(sql, pageable, DiagnoseResultInfo.class);
        //设置PageDto
        List<DiagnoseResultInfo> diagnoseManages = page.getContent();
        long total = page.getTotalElements();
        PageDto pageDto = new PageDto();
        pageDto.setRows(diagnoseManages);
        pageDto.setTotal(total);
        return pageDto;
    }

}
